
class Lockable {
 public:
  Lockable ();
  bool readLock  ();                              /* read-locks whole resource */
  bool writeLock ();                              /* global write-lock    */
  bool writeLock (int rowNum, bool block = true); /* row-level write lock */

  bool readUnlock  ();
  bool writeUnlock ();
  bool writeUnlock (int rowNum);

  void attachReader ();
  void detachReader ();

 private:
  int writerCount;

  Mutex writerCountMutex;
  Cond  writerCountCond;

  int readerCount;

  Mutex readerCountMutex;
  Cond  readerCountCond;

  bool readLocked;
  bool writeLocked;

  Mutex readLockedMutex;
  Cond  readLockedCond;

  Mutex writeLockedMutex;
  Cond  writeLockedCond;

  set<int> writeLockedRows;

  Mutex writeLockedRowsMutex;
  map<int, Cond> writeLockedRowsCond;
};

